package com.xes.attend.rd60n.jiecard.cn;

import java.io.UnsupportedEncodingException;
import java.nio.ByteOrder;
import java.nio.charset.Charset;

import struct.JavaStruct;

public class RD60N {
	private NetConn conn = null;

	private CmdData send_recv_udp(byte[] param_data, byte cmd_id) {

		CmdData cmd = new CmdData(param_data, cmd_id);
		CmdData result = null;
		try {
			do {
				byte[] data = JavaStruct.pack(cmd, ByteOrder.LITTLE_ENDIAN);
				if (0 != conn.SendData(data))
					break;
				data = conn.RecvData(0);
				if (null == data)
					break;
				if (data[0] != (byte) 0xAB)
					break;
				if (data[5] != data.length)
					break;
//				if (data[6] != cmd_id)
//					break;
				byte crc = 0;
				for (int i = 0; i < data.length-1; ++i) {
					crc = (byte) (crc ^ data[i]);
				}

				if (crc != data[data.length - 1])
					break;
				data[5] -= 9;
				result = new CmdData(null, (byte) 0);
				JavaStruct.unpack(result, data, ByteOrder.LITTLE_ENDIAN);

			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = null;
		}

		return result;
	}

	private CmdData send_recv_tcp(byte[] param_data, byte cmd_id) {

		CmdData cmd = new CmdData(param_data, cmd_id);
		CmdData result = null;
		try {
			do {
				byte[] data = JavaStruct.pack(cmd, ByteOrder.LITTLE_ENDIAN);
				if (0 != conn.SendData(data))
					break;
				data = conn.RecvData(8);
				if (null == data)
					break;
				if (data[0] != (byte) 0xAB)
					break;
				if (data[5] < 10)
					break;
				if (data[6] != cmd_id)
					break;
				byte[] data2 = conn.RecvData(data[5] - 8);
				if (null == data2)
					break;
				byte crc = 0;
				for (int i = 0; i < data.length; ++i) {
					crc = (byte) (crc ^ data[i]);
				}
				for (int i = 0; i < data2.length - 1; ++i) {
					crc = (byte) (crc ^ data2[i]);
				}
				if (crc != data2[data2.length - 1])
					break;
				byte[] recv_data = new byte[data[5]];
				System.arraycopy(data, 0, recv_data, 0, 8);
				System.arraycopy(data2, 0, recv_data, 8, data2.length);
				recv_data[5] -= 9;
				result = new CmdData(null, (byte) 0);
				JavaStruct.unpack(result, recv_data, ByteOrder.LITTLE_ENDIAN);

			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = null;
		}

		return result;
	}

	private CmdData send_recv(byte[] param_data, byte cmd_id) {
		if(conn.getClass()== UDPClientConn.class) {
			return send_recv_udp(param_data,cmd_id);
		}
		else if(conn.getClass()== TCPClientConn.class){
			
		}
		else if(conn.getClass() == TCPServerConn.class){
			return send_recv_tcp(param_data,cmd_id);
		}
		return null;
	}

	private static byte[] toLH(int v) {
		byte[] b = new byte[4];
		b[0] = (byte) (v & 0xff);
		b[1] = (byte) (v >> 8 & 0xff);
		b[2] = (byte) (v >> 16 & 0xff);
		b[3] = (byte) (v >> 24 & 0xff);
		return b;
	}

	private static byte[] toLH(short v) {
		byte[] b = new byte[2];
		b[0] = (byte) (v & 0xff);
		b[1] = (byte) (v >> 8 & 0xff);
		return b;
	}

	private static short lBytesToShort(byte[] b) {
		int s = 0;
		if (b[1] >= 0) {
			s = s + b[1];
		} else {
			s = s + 256 + b[1];
		}
		s = s * 256;
		if (b[0] >= 0) {
			s = s + b[0];
		} else {
			s = s + 256 + b[0];
		}
		return (short) s;

	}

	private static int lBytesToInt(byte[] b) {
		int s = 0;
		for (int i = 0; i < 3; i++) {
			if (b[3 - i] >= 0) {
				s = s + b[3 - i];
			} else {
				s = s + 256 + b[3 - i];
			}
			s = s * 256;
		}
		if (b[0] >= 0) {
			s = s + b[0];
		} else {
			s = s + 256 + b[0];
		}
		return s;
	}
	private void ByteToString(byte[] data,StringBuilder str) throws UnsupportedEncodingException
	{
		str.delete(0, str.length());
		str.append(new String(data,"GBK"));
	}

	public int rf_open(String ip, String prop) {
		int result = 1;

		String p = prop.toUpperCase();
		try {
			if (p == "TCP") {
				conn = new TCPClientConn(ip);
				result = 0;
			} else if (p == "UDP") {
				conn = new UDPClientConn(ip);
				result = 0;
			}
		} catch (Exception e) {
			result = 1;
		}
		return result;
	}

	public void rf_open(NetConn _conn) {
		rf_close();
		conn = _conn;
	}

	public int rf_close() {
		int result = 1;
		try {
			conn.Close();
			result = 0;
		} catch (Exception e) {
			result = 1;
		}

		return result;
	}

	public int rf_card(byte[] atq, byte[] ack, byte[] card_sn, byte halt) {

		int result = 1;
		try {
			do {
				CmdParamOneByte send_param = new CmdParamOneByte();
				send_param.value = halt;
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_ACTIVE_CARD);
				if (res == null)
					break;
				result = res.cmd_result;
				if (0 == result) {
					CmdParamCardActive recv_param = new CmdParamCardActive();
					JavaStruct.unpack(recv_param, res.data,
							ByteOrder.LITTLE_ENDIAN);
					System.arraycopy(recv_param.card_atq, 0, atq, 0,
							recv_param.card_atq.length);
					System.arraycopy(recv_param.card_ack, 0, ack, 0,
							recv_param.card_ack.length);
					System.arraycopy(recv_param.card_sn, 0, card_sn, 0,
							recv_param.card_sn.length);
				}
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_request(byte _mode, byte[] atq) {
		int result = 1;
		try {
			do {
				CmdParamOneByte send_param = new CmdParamOneByte();
				send_param.value = _mode;
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_REQUEST);
				if (res == null)
					break;
				result = res.cmd_result;
				if (0 == result) {
					CmdParamCardRequest recv_param = new CmdParamCardRequest();
					JavaStruct.unpack(recv_param, res.data,
							ByteOrder.LITTLE_ENDIAN);
					System.arraycopy(recv_param.card_atq, 0, atq, 0,
							recv_param.card_atq.length);
				}
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;

	}

	public int rf_anticoll(byte[] card_sn) {
		int result = 1;
		try {
			do {
				CmdParamOneByte send_param = new CmdParamOneByte();
				send_param.value = 0;
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_ANTICOLL);
				if (res == null)
					break;
				result = res.cmd_result;
				if (0 == result) {
					CmdParamCardSelect recv_param = new CmdParamCardSelect();
					JavaStruct.unpack(recv_param, res.data,
							ByteOrder.LITTLE_ENDIAN);
					System.arraycopy(recv_param.card_sn, 0, card_sn, 0,
							recv_param.card_sn.length);
				}
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_select(byte[] card_sn, byte[] ack) {

		int result = 1;
		try {
			do {
				CmdParamCardSelect send_param = new CmdParamCardSelect();
				System.arraycopy(card_sn, 0, send_param.card_sn, 0, 4);
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_SELECT);
				if (res == null)
					break;
				result = res.cmd_result;
				if (0 == result) {
					CmdParamOneByte recv_param = new CmdParamOneByte();
					JavaStruct.unpack(recv_param, res.data,
							ByteOrder.LITTLE_ENDIAN);
					ack[0] = recv_param.value;
				}
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_authent(byte mode, byte[] card_sn, byte sector,
			byte[] password) {
		int result = 1;
		try {
			do {
				CmdParamCardAuth send_param = new CmdParamCardAuth();
				send_param.auth_mode = mode;
				send_param.auth_sect = sector;

				System.arraycopy(card_sn, 0, send_param.card_sn, 0, 4);
				System.arraycopy(password, 0, send_param.pass_word, 0, 6);
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_AUTHENT);
				if (res == null)
					break;
				result = res.cmd_result;

			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;

	}

	public int rf_read(byte block, byte[] data) {
		int result = 1;
		try {
			do {
				CmdParamOneByte send_param = new CmdParamOneByte();
				send_param.value = block;
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_READ);
				if (res == null)
					break;
				result = res.cmd_result;
				if (0 == result) {
					CmdParamCardRead recv_param = new CmdParamCardRead();
					JavaStruct.unpack(recv_param, res.data,
							ByteOrder.LITTLE_ENDIAN);
					System.arraycopy(recv_param.card_data, 0, data, 0,
							recv_param.card_data.length);
				}
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_write(byte block, byte[] Data) {
		int result = 1;
		try {
			do {
				CmdParamCardWrite send_param = new CmdParamCardWrite();
				send_param.block = block;
				System.arraycopy(Data, 0, send_param.card_data, 0, 16);
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_WRITE);
				if (res == null)
					break;
				result = res.cmd_result;
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_halt() {
		int result = 1;
		try {
			do {
				CmdParamOneByte send_param = new CmdParamOneByte();
				send_param.value = 0;
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_HALT);
				if (res == null)
					break;
				result = res.cmd_result;
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;

	}

	public int rf_beep(byte _10ms) {
		int result = 1;
		try {
			do {
				CmdParamOneByte send_param = new CmdParamOneByte();
				send_param.value = _10ms;
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_BEEP);
				if (res == null)
					break;
				result = res.cmd_result;
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_display(byte line, String text, byte sec) {

		int result = 1;
		try {
			do {
				CmdParamDisplay send_param = new CmdParamDisplay();
				send_param.line = line;
				send_param.dela_s = sec;
				byte[] s = text.getBytes(Charset.forName("GBK"));
				System.arraycopy(s, 0, send_param.text, 0, s.length);
				send_param.text[s.length] = 0;
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_DISP);
				if (res == null)
					break;
				result = res.cmd_result;
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_relay_on(int _ms) {
		int result = 1;
		try {
			do {
				CmdParamRelay send_param = new CmdParamRelay();
				System.arraycopy(toLH(_ms), 0, send_param.dela_ms, 0, 4);
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_RELAY_ON);
				if (res == null)
					break;
				result = res.cmd_result;
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_set_datetime(short[] datetime) {
		int result = 1;
		try {
			do {
				CmdParamDatetime send_param = new CmdParamDatetime();
				send_param.y = (byte) (datetime[0] - 2000);
				send_param.m = (byte) datetime[1];
				send_param.d = (byte) datetime[2];
				send_param.h = (byte) datetime[3];
				send_param.n = (byte) datetime[4];
				send_param.s = (byte) datetime[5];
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_SETTIME);
				if (res == null)
					break;
				result = res.cmd_result;
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_set_ipaddr(String ip, String mask, String gw) {
		byte[] s;
		int result = 1;
		try {
			do {
				CmdParamIPaddr send_param = new CmdParamIPaddr();
				s = ip.getBytes(Charset.forName("GBK"));
				System.arraycopy(s, 0, send_param.ip, 0, s.length);
				send_param.ip[s.length - 1] = 0;

				s = mask.getBytes(Charset.forName("GBK"));
				System.arraycopy(s, 0, send_param.mask, 0, s.length);
				send_param.mask[s.length - 1] = 0;

				s = gw.getBytes(Charset.forName("GBK"));
				System.arraycopy(s, 0, send_param.gw, 0, s.length);
				send_param.gw[s.length - 1] = 0;

				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_SETIP);
				if (res == null)
					break;
				result = res.cmd_result;
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_set_server(String ip, short port, byte mode) {
		byte[] s;
		int result = 1;
		try {
			do {
				CmdParamServer send_param = new CmdParamServer();
				s = ip.getBytes(Charset.forName("GBK"));
				System.arraycopy(s, 0, send_param.server, 0, s.length);
				send_param.server[s.length - 1] = 0;

				System.arraycopy(toLH(port), 0, send_param.port, 0, 2);
				send_param.mode = mode;

				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_SETSERV);
				if (res == null)
					break;
				result = res.cmd_result;
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_set_lcd_backlight(byte bl) {
		int result = 1;
		try {
			do {
				CmdParamOneByte send_param = new CmdParamOneByte();
				send_param.value = bl;

				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_SET_LCD_BL);
				if (res == null)
					break;
				result = res.cmd_result;
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_set_lcd_backlight_temp(byte bl_1, byte bl_2, byte sec) {
		int result = 1;
		try {
			do {
				CmdParamBacklightTemp send_param = new CmdParamBacklightTemp();
				send_param.backlight = bl_1;
				send_param.backlight_return = bl_2;
				send_param.delay_s = sec;

				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_SET_LCD_BL_TMP);
				if (res == null)
					break;
				result = res.cmd_result;
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_set_lcd_title(String title) {

		int result = 1;
		try {
			do {
				CmdParamLcdTitle send_param = new CmdParamLcdTitle();
				byte[] s = title.getBytes(Charset.forName("GBK"));
				System.arraycopy(s, 0, send_param.title, 0, s.length);
				send_param.title[s.length - 1] = 0;

				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_SET_LCD_TITLE);
				if (res == null)
					break;
				result = res.cmd_result;
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_set_dns(String dns1, String dns2) {
		byte[] s;
		int result = 1;
		try {
			do {
				CmdParamDns send_param = new CmdParamDns();
				s = dns1.getBytes(Charset.forName("GBK"));
				System.arraycopy(s, 0, send_param.dns_1, 0, s.length);
				send_param.dns_1[s.length - 1] = 0;

				s = dns2.getBytes(Charset.forName("GBK"));
				System.arraycopy(s, 0, send_param.dns_2, 0, s.length);
				send_param.dns_2[s.length - 1] = 0;

				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_SETDNS);
				if (res == null)
					break;
				result = res.cmd_result;
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;

	}

	public int rf_get_info(StringBuilder info) {

		int result = 1;
		try {
			do {
				CmdParamOneByte send_param = new CmdParamOneByte();
				send_param.value = 0;
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_GETVER);
				if (res == null)
					break;
				result = res.cmd_result;
				if (0 == result) {
					CmdParamInfo recv_param = new CmdParamInfo();
					JavaStruct.unpack(recv_param, res.data,
							ByteOrder.LITTLE_ENDIAN);
					info.delete(0, info.length());
					info.append(recv_param.info);
				}
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_get_datetime(short[] datetime) {
		int result = 1;
		try {
			do {
				CmdParamOneByte send_param = new CmdParamOneByte();
				send_param.value = 0;
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_GETTIME);
				if (res == null)
					break;
				result = res.cmd_result;
				if (0 == result) {
					CmdParamDatetime recv_param = new CmdParamDatetime();
					JavaStruct.unpack(recv_param, res.data,
							ByteOrder.LITTLE_ENDIAN);
					datetime[0] = (short) (recv_param.y + 2000);
					datetime[1] = recv_param.m;
					datetime[2] = recv_param.d;
					datetime[3] = recv_param.h;
					datetime[4] = recv_param.n;
					datetime[5] = recv_param.s;
				}
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_get_ipaddr(StringBuilder ip, StringBuilder mask,
			StringBuilder gw) {
		int result = 1;
		try {
			do {
				CmdParamOneByte send_param = new CmdParamOneByte();
				send_param.value = 0;
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_GETIP);
				if (res == null)
					break;
				result = res.cmd_result;
				if (0 == result) {
					CmdParamIPaddr recv_param = new CmdParamIPaddr();
					
					JavaStruct.unpack(recv_param, res.data,
							ByteOrder.LITTLE_ENDIAN);
					
					ByteToString(recv_param.ip,ip);
					ByteToString(recv_param.mask,mask);
					ByteToString(recv_param.gw,gw);
				}
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_get_server(StringBuilder ip, short[] port, byte[] mode) {
		int result = 1;
		try {
			do {
				CmdParamOneByte send_param = new CmdParamOneByte();
				send_param.value = 0;
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_GETSERV);
				if (res == null)
					break;
				result = res.cmd_result;
				if (0 == result) {
					CmdParamServer recv_param = new CmdParamServer();
					JavaStruct.unpack(recv_param, res.data,
							ByteOrder.LITTLE_ENDIAN);
					ByteToString(recv_param.server,ip);

					port[0] = lBytesToShort(recv_param.port);
					mode[0] = recv_param.mode;
				}
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_get_dns(StringBuilder dns1, StringBuilder dns2) {
		int result = 1;
		try {
			do {
				CmdParamOneByte send_param = new CmdParamOneByte();
				send_param.value = 0;
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_GETDNS);
				if (res == null)
					break;
				result = res.cmd_result;
				if (0 == result) {
					CmdParamDns recv_param = new CmdParamDns();
					JavaStruct.unpack(recv_param, res.data,
							ByteOrder.LITTLE_ENDIAN);
					ByteToString(recv_param.dns_1,dns1);
					ByteToString(recv_param.dns_2,dns2);

				}
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_get_switch_ex(byte[] switch_status) {
		int result = 1;
		try {
			do {
				CmdParamOneByte send_param = new CmdParamOneByte();
				send_param.value = 0;
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_GETDNS);
				if (res == null)
					break;
				result = res.cmd_result;
				if (0 == result) {
					CmdParamOneByte recv_param = new CmdParamOneByte();
					JavaStruct.unpack(recv_param, res.data,
							ByteOrder.LITTLE_ENDIAN);
					switch_status[0] = recv_param.value;
				}
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_set_reset() {
		int result = 1;
		try {
			do {
				CmdParamOneByte send_param = new CmdParamOneByte();
				send_param.value = 0;
				CmdData res = send_recv(JavaStruct.pack(send_param),
						CmdData.CMD_ID_RESTART);
				if (res == null)
					break;
				result = res.cmd_result;
			} while (false);
		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;
	}

	public int rf_card_confirm(byte[] card_sn, byte auto_request) {
		int result = 1;
		try {

			CmdParamCardConfirm send_param = new CmdParamCardConfirm();
			send_param.auto_request = auto_request;
			System.arraycopy(card_sn, 0, send_param.card_sn, 0, 4);
			CmdData data = new CmdData(JavaStruct.pack(send_param),
					CmdData.CMD_ID_CARD_CONFIRM);
			conn.SendData(JavaStruct.pack(data));
			result = 0;

		} catch (Exception e) {
			e.printStackTrace();
			result = 1;
			rf_close();
		}
		return result;

	}

	public int rf_conn_info(StringBuilder ip, short[] port) {
		if (null != conn) {
			ip.delete(0, ip.length());
			ip.append(conn.ConnIpAddr());
			port[0] = (short) conn.ConnPort();
			return 0;
		} else {
			return 1;
		}

	}

}
